#!/usr/bin/python
import re
from configmod.configobj import validate

def all(it, pred=bool):
    for x in it:
        if not pred(x):
            return False
    return True

route_regexp = re.compile("""
    (\d+).(\d+).(\d+).(\d+)/(\d+)
    \s+
    (\d+).(\d+).(\d+).(\d+)
    \s+
    (\d+)""", re.VERBOSE)

def route(value, maxcost=10):
    """Validator four route values.
    
    Example of valid route: 10.0.1.0/8 192.168.1.1 10.
    """ 
    match = route_regexp.match(value)
    if not match or len(match.groups()) != 10: 
        raise validate.VdtTypeError(value)
    try:
        fields = map(int, match.groups())
    except ValueError:
        raise validate.VdtTypeError(value)
    ipvalues = [fields[index] for index in (0, 1, 2, 3, 5, 6, 7, 8)]
    if (not all(0 <= x <= 255 for x in ipvalues) or 
            not 0 <= fields[4] <= 32 or 
            not 0 <= fields[9] <= maxcost):                
        raise validate.VdtTypeError(value)
    return value                
           
def route_list(values,  min=None, max=None, maxcost=10):
    """Validate a list of routes."""
    return [route(s, maxcost) for s in validate.is_list(values, min, max)]
        
ospf_network_regexp = re.compile("""
    (\d+).(\d+).(\d+).(\d+)/(\d+)
    \s+
    area
    \s+
    (\d+).(\d+).(\d+).(\d+)""", re.VERBOSE)

def ospf_network(value):
    """Validator four route values.
    
    Example of valid route: "10.11.1.0/28 area 0.0.0.1".
    """ 
    match = ospf_network_regexp.match(value)
    if not match or len(match.groups()) != 9: 
        raise validate.VdtTypeError(value)
    try:
        fields = map(int, match.groups())
    except ValueError:
        raise validate.VdtTypeError(value)
    ipvalues = [fields[index] for index in (0, 1, 2, 3, 5, 6, 7, 8)]
    if (not all(0 <= x <= 255 for x in ipvalues) or 
            not 0 <= fields[4] <= 32): 
        raise validate.VdtTypeError(value)
    return value                

def ospf_network_list(values,  min=None, max=None):
    """Validate a list of routes."""
    return [ospf_network(s) for s in validate.is_list(values, min, max)]


ospf_area_regexp = re.compile("""
    (\d+).(\d+).(\d+).(\d+)
    \s+
    range
    \s+
    (\d+).(\d+).(\d+).(\d+)/(\d+)""", re.VERBOSE)

def ospf_area(value):
    """Validator four route values.
    
    Example of valid route: "0.0.0.1 range 1.1.1.0/2".
    """ 
    match = ospf_area_regexp.match(value)
    if not match or len(match.groups()) != 9: 
        raise validate.VdtTypeError(value)
    try:
        fields = map(int, match.groups())
    except ValueError:
        raise validate.VdtTypeError(value)
    ipvalues = [fields[index] for index in (0, 1, 2, 3, 4, 5, 6, 7)]
    if (not all(0 <= x <= 255 for x in ipvalues) or 
            not 0 <= fields[8] <= 32): 
        raise validate.VdtTypeError(value)
    return value                

def ospf_area_list(values,  min=None, max=None):
    """Validate a list of routes."""
    return [ospf_area(s) for s in validate.is_list(values, min, max)]

def get_validators():
    return dict(
        route=route,
        route_list=route_list,
        ospf_network=ospf_network,
        ospf_network_list=ospf_network_list,
        ospf_area=ospf_area,
        ospf_area_list=ospf_area_list,
    )
